package com.fangyi.yunmusic.utils;

import com.fangyi.yunmusic.enums.FileTypeEnum;
import com.fangyi.yunmusic.config.ResourceConfig;
import com.fangyi.yunmusic.exception.YunMusicException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;

@Component
public class FileUploadClient {

    private Logger logger = LoggerFactory.getLogger(FileUploadClient.class);

    @Autowired
    private ResourceConfig resourceConfig;

    public FileMessageResponse uploadToFarService(MultipartFile file, FileTypeEnum fileType) {
        FileUploadClient.FileUploadResponse response = uploadToFarServiceByHttpClient(file, fileType);
        if (response.getStatus() != 200) {
            // 上传失败，抛出异常
            throw new YunMusicException(response.getMsg());
        }
        // 上传成功，返回文件名
        String filename = response.getData().getName();
        // 得到“.”之前的内容
        String fileId = filename.split("\\.")[0];
        FileMessageResponse messageResponse = new FileMessageResponse();
        messageResponse.setFileId(fileId);
        // 得到绝对路径
        messageResponse.setFilePath(getRemoteFilePath(fileId, fileType));
        return messageResponse;
    }

    private String getRemoteFilePath(String fileId, FileTypeEnum fileType) {
        if (fileType == FileTypeEnum.USER_AVATAR) {
            return resourceConfig.getUserAvatarUrl(fileId);
        } else if (fileType == FileTypeEnum.PLAYLIST_COVER) {
            return resourceConfig.getPlaylistCoverUrl(fileId);
        } else if (fileType == FileTypeEnum.ALBUM_COVER) {
            return resourceConfig.getAlbumCoverUrl(fileId);
        } else if (fileType == FileTypeEnum.SINGER_COVER) {
            return resourceConfig.getArtistPicUrl(fileId);
        } else if (fileType == FileTypeEnum.SONG) {
            return resourceConfig.getSongUrl(fileId);
        } else {
            throw new YunMusicException("不支持的枚举");
        }
    }

    private FileUploadResponse uploadToFarServiceByHttpClient(MultipartFile file, FileTypeEnum fileType) {
        // 可优化
        HttpClientConnectionManager clientConnectionManager = new BasicHttpClientConnectionManager();
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create().setConnectionManager(clientConnectionManager);
        HttpClient httpclient = httpClientBuilder.build();
        try {
            HttpPost httppost = new HttpPost(resourceConfig.getUploadServer() + "?fileType=" + fileType.getValue());
            MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();

            FileBody filebdody = new FileBody(inputStreamTofile(
                    file.getInputStream(), file.getName()));
            multipartEntityBuilder.addPart(file.getName(), filebdody);
            httppost.setEntity(multipartEntityBuilder.build());
            HttpResponse response = httpclient.execute(httppost);

            int statusCode = response.getStatusLine().getStatusCode();

            if (statusCode == HttpStatus.SC_OK) {
                logger.info("文件上传服务器正常响应.....");
                HttpEntity resEntity = response.getEntity();
                String remoteResponse = EntityUtils.toString(resEntity,"UTF-8");// httpclient自带的工具类读取返回数据
                FileUploadResponse jsonResponse = JsonUtils.jsonToPojo(remoteResponse, FileUploadResponse.class);
                EntityUtils.consume(resEntity);
                return jsonResponse;
            } else {
                throw new YunMusicException(EntityUtils.toString(response.getEntity(),"UTF-8"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                clientConnectionManager.shutdown();
            } catch (Exception ignore) {

            }
        }
        return null;
    }

    private File inputStreamTofile(InputStream ins, String filename)
            throws IOException {
        File file = new File(filename);
        OutputStream os = new FileOutputStream(file);
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        os.close();
        ins.close();
        return file;
    }

    public  static class FileMessageResponse {
        private String filePath;
        private String fileId;

        public String getFilePath() {
            return filePath;
        }

        public void setFilePath(String filePath) {
            this.filePath = filePath;
        }

        public String getFileId() {
            return fileId;
        }

        public void setFileId(String fileId) {
            this.fileId = fileId;
        }
    }

    public static class FileUploadResponse {
        private static final Integer OK = 200, ERROR = 500;

        private Integer status;
        private String msg;
        private FileMessage data;

        public Integer getStatus() {
            return status;
        }

        public void setStatus(Integer status) {
            this.status = status;
        }

        public String getMsg() {
            return msg;
        }

        public void setMsg(String msg) {
            this.msg = msg;
        }

        public FileMessage getData() {
            return data;
        }

        public void setData(FileMessage data) {
            this.data = data;
        }

        @Override
        public String toString() {
            return "FileUploadResponse{" +
                    "status=" + status +
                    ", msg='" + msg + '\'' +
                    ", data=" + data +
                    '}';
        }

        public static class FileMessage {
            private String name;

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            @Override
            public String toString() {
                return "FileMessage{" +
                        "name='" + name + '\'' +
                        '}';
            }
        }
    }


}
